package com.bangcommunity.bbframe.mybatis.plugins;

import com.bangcommunity.bbframe.config.QtMonitorConfig;
import com.bangcommunity.bbframe.mlog.logger.MLogFacade;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import com.bangcommunity.bbframe.mybatis.utils.MybatisUtils;

/**
 *
 * @author tanghc
 * @since v0.0.1
 */
/**
 *
 * 基于Mybatis实现的SQL监视器，实现对象SQL拦截，以便可以将每个操作SQL记入日志中
 *
 */
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }),
        @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
                RowBounds.class, ResultHandler.class }) })
public class MonitorInterceptor extends AbstractInterceptor {

    static int MAPPED_STATEMENT_INDEX = 0;
    static int PARAMETER_INDEX = 1;

    private Boolean enableMonitor = QtMonitorConfig.mybatis_on;

    @Override
    public Object intercept(Invocation invoker) throws Throwable {
        if (MLogFacade.isMLogTraceEnable()) {
            MLogFacade.trace("========== monitor ====  mybatis  ==========");
        }
        long time = System.currentTimeMillis();
        try {
            return invoker.proceed();
        } finally {
            printsql(invoker);
            if (MLogFacade.isMLogTraceEnable()) {
                MLogFacade.trace("Runing time: " + String.valueOf(System.currentTimeMillis() - time) + "ms");
            }
        }
    }

    protected void printsql(Invocation invoker) {
        Object[] queryArgs = invoker.getArgs();
        MappedStatement ms = (MappedStatement) queryArgs[MAPPED_STATEMENT_INDEX];
        Object parameterObject = queryArgs[PARAMETER_INDEX];
        String sql = MybatisUtils.getFilledSql(ms, parameterObject);
        if (MLogFacade.isMLogTraceEnable()) {
            MLogFacade.trace("SQL MESSAGE:{} : {}", ms.getId(), sql);
        }
    }
}
